博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
TextView SpannableString 使用之实现可点击超链接效果
阅读量:5902 次
发布时间:2019-06-19

本文共 5089 字,大约阅读时间需要 16 分钟。

TextView SpannableString 使用之实现可点击超链接效果

如果看到这里说明你对 TextView 已经有了一定的了解,至少已经使用过该控件显示文字过。现在来实现一些复杂一点的效果。

1. 实现可点击的超链接

我们在APP开发过程中会遇到这样的需求,例如:

图片描述

其中标记为下划线的为可点击,点击后一般是跳转一个网页(这个在这里不做讨论)。面对这样的需求里可能已经知道TextView是可以添加下划线的,你的实现可能是:

By Login, You agree to our Privicy Policy & Terms of use[TextView]----[TextView]--[TextView]---[TextView][By Login, You agree to our ][Privicy Policy][ & ][Terms of use]

然后为可点击的 TextView添加下划线,然后设置点击事件就ok了。

如果你满足于这,那么你可以继续往后看,看看只用一个TextView 如何实现。

2. 可点击的超链接(基础)

为了介绍 SpannableString,我们来用它实现一个简单的下划线并设置监听点击事件。

图片描述

String clickString = "I Love Android!";        SpannableString spannableString =new SpannableString(clickString);        spannableString.setSpan(new ClickableSpan() {            @Override            public void onClick(View widget) {                Toast.makeText(getActivity(),"Love",Toast.LENGTH_SHORT).show();            }        },2,6,Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);        tv_tip.setText(spannableString);        tv_tip.setMovementMethod(LinkMovementMethod.getInstance());

3. 多个可点击的超链接(提高)

这回就要使用一个新的类:SpannableStringBuilder。看到名字就知道,它的作用类似StringBuilder就是把多个SpannableString连接起来。

最后的效果:

图片描述

点击效果:

图片描述

代码实现(关键点就是把多个SpannableString连接起来):

final String linkWord1 = "Android";        final String linkWord2 = "Are you ok?";        final String linkWord3 = "think you!";        String word = "Hello " + linkWord1 + "," + linkWord2 + " I'm fine," + linkWord3;        SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(word);        int index1 = word.indexOf(linkWord1);        int index2 = word.indexOf(linkWord2);        int index3 = word.indexOf(linkWord3);        spannableStringBuilder.setSpan(new ClickableSpan() {            @Override            public void onClick(View widget) {                Toast.makeText(getActivity(), linkWord1, Toast.LENGTH_SHORT).show();            }            @Override            public void updateDrawState(TextPaint ds) {                super.updateDrawState(ds);                ds.setColor(Color.RED);       //设置文件颜色                ds.setUnderlineText(true);      //设置下划线            }        }, index1, index1 + linkWord1.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);        spannableStringBuilder.setSpan(new ClickableSpan() {            @Override            public void onClick(View widget) {                Toast.makeText(getActivity(), linkWord2, Toast.LENGTH_SHORT).show();            }            @Override            public void updateDrawState(TextPaint ds) {                super.updateDrawState(ds);                ds.setColor(Color.GREEN);       //设置文件颜色                ds.setUnderlineText(true);      //设置下划线            }        }, index2, index2 + linkWord2.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);        spannableStringBuilder.setSpan(new ClickableSpan() {            @Override            public void onClick(View widget) {                Toast.makeText(getActivity(), linkWord3, Toast.LENGTH_SHORT).show();            }            @Override            public void updateDrawState(TextPaint ds) {                super.updateDrawState(ds);                ds.setColor(Color.BLUE);       //设置文件颜色                ds.setUnderlineText(false);      //设置下划线            }        }, index3, index3 + linkWord3.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);        tv_tip.setTextSize(14);        tv_tip.setText(spannableStringBuilder);        tv_tip.setMovementMethod(LinkMovementMethod.getInstance());

4. 多个可点击的超链接(html)

当然还有另外一种方法,就是使用TextView显示 html格式的文本,然后处理其中的url,过程还是类似我们上面用到的方法,直接上代码吧:

String html = "

\n" + " Hello AndroidAre you ok?I'm fine,think you!\n" + "

"; tv_tip.setText(Html.fromHtml(html)); tv_tip.setMovementMethod(LinkMovementMethod.getInstance()); CharSequence text = tv_tip.getText(); if (text instanceof Spannable) { int end = text.length(); Spannable sp = (Spannable) tv_tip.getText(); URLSpan[] urls = sp.getSpans(0, end, URLSpan.class); SpannableStringBuilder style = new SpannableStringBuilder(text); style.clearSpans(); // should clear old spans for (final URLSpan url : urls) { // 设置Span style.setSpan(new ClickableSpan() { @Override public void onClick(View widget) { Toast.makeText(getActivity(), url.getURL(), Toast.LENGTH_SHORT).show(); } @Override public void updateDrawState(TextPaint ds) { super.updateDrawState(ds); ds.setColor(Color.RED); //设置文件颜色 ds.setUnderlineText(true); //设置下划线 } }, sp.getSpanStart(url), sp.getSpanEnd(url), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } tv_tip.setText(style); }

效果图:

因为我把所有的连接都设置为红色,所以显示的都是红色,实际中可能进行处理,那时对每个url都进行处理即可。

图片描述

这里我没有讲每个类的细节,因为我觉得,如果你知道类名,那么你可以查到对应的官方文档,官方文档对api的讲解是很详细的,但是官方很少会结合实际需求告诉你如何实现,可能某一个api你不熟悉你就无法和实际需求联想起来,希望看了 这篇文章想深入了解的可以从 CharSequence 接口(与上面的类紧密联系)进行展开。

下一篇讲 TextView ImageSpan 实现文字图片混排。

转载地址:http://qyupx.baihongyu.com/

你可能感兴趣的文章
Content Provider 基础 之URI
查看>>
ios获取安装的app
查看>>
Visual Studio 2012出现“无法访问T-SQL组件和安装了不兼容伯 DacFx版本”的解决办法...
查看>>
第一个版本
查看>>
JSTL I18N 格式标签库 使用之二_____读取消息资源
查看>>
聊聊NettyConnector的start及shutdown
查看>>
Raffi Krikorian 为“在运行中进行架构重写”提供了指南
查看>>
OneAPM挂牌新三板,续写ITOM新篇章
查看>>
通过源码解析 Node.js 中一个 HTTP 请求到响应的历程
查看>>
做了一点事,学到了一些
查看>>
CodeIgniter的密码处理论
查看>>
深入Mysql - 谈谈我对数据类型的认识
查看>>
Tsuru 1.7.0-rc4 发布,基于 Docker 的 PaaS 框架
查看>>
Apache HBase 2.1.3 发布,分布式数据库
查看>>
微信端H5开发整体解决方案
查看>>
Python之retrying
查看>>
OWASP 10 大 Web 安全问题在 JEE 体系完全失控
查看>>
洛谷 P1640 BZOJ 1854 [SCOI2010]连续攻击游戏
查看>>
如何理解Unity组件化开发模式
查看>>
util.promisify 的那些事儿
查看>>